-
Notifications
You must be signed in to change notification settings - Fork 346
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
rewrite.rs
: refactor new_parents
to depend only on parent_mapping
#2646
Conversation
6a6f499
to
ea7f3f5
Compare
59ef635
to
149df31
Compare
c5f1b89
to
fa5fd1a
Compare
I added a few comments. I realized that, for other uses, the assertion that replacements are non-empty might be unnecessary, but I'm not sure when if ever other uses might come up. |
See comments inline for details. In particular, I wanted to make sure these behaviors are not affected by jj-vcs#2646. They don't seem to be.
See comments inline for details. Cc jj-vcs#2600. In particular, I wanted to make sure these behaviors are not affected by jj-vcs#2646. They don't seem to be.
See comments inline for details. Cc jj-vcs#2600. In particular, I wanted to make sure these behaviors are not affected by jj-vcs#2646. They don't seem to be. The tests ended up weirder than expected because of jj-vcs#2600 (comment). Even though, for now, the behavior of tests is unaffected by that issue, the *expected* behavior is different.
See comments inline for details. Cc jj-vcs#2600. In particular, I wanted to make sure these behaviors are not affected by jj-vcs#2646. They don't seem to be. The tests ended up weirder than expected because of jj-vcs#2600 (comment). Even though, right now, the behavior of tests is unaffected by that issue, the *expected* behavior is different.
new_parents
to depend only on parent_mapping
rewrite.rs
: refactor new_parents
to depend only on parent_mapping
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't have much expertise on rebase code, but I think we agreed that the change direction is good, so I went ahead and marked as approved.
See comments inline for details. Cc #2600. In particular, I wanted to make sure these behaviors are not affected by #2646. They don't seem to be. The tests ended up weirder than expected because of #2600 (comment). Even though, right now, the behavior of tests is unaffected by that issue, the *expected* behavior is different.
I'm thinking of maybe waiting until the next release (which is, I'm guessing, planned for Wednesday) before merging this, since I doubt I'll have time to implement any user-visible bugfixes or features that use this PR before that. |
f237963
to
8dd1e63
Compare
As suggested by @yuja in jj-vcs#2646 (comment)
As suggested by @yuja in jj-vcs#2646 (comment)
Planning to merge this in ~24 hours. |
As suggested by @yuja in jj-vcs#2646 (comment)
Previously, the function relied on both the `self.parent_mapping` and `self.rebased`. If `(A,B)` was in `parent_mapping` and `(B,C)` was in `rebased`, `new_parents` would map `A` to `C`. Now, `self.rebased` is ignored by `new_parents`. In the same situation, DescendantRebaser is changed so that both `(A,B)` and `(B,C)` are in `parent_mapping` before. `new_parents` now applies `parent_mapping` repeatedly, and will map `A` to `C` in this situation. ## Cons - The semantics are changed; `new_parents` now panics if `self.parent_mapping` contain cycles. AFAICT, such cycles never happen in `jj` anyway, except for one test that I had to fix. I think it's a sensible restriction to live with; if you do want to swap children of two commits, you can call `rebase_descendants` twice. ## Pros - I find the new logic much easier to reason about. I plan to extract it into a function, to be used in refactors for `jj rebase -r` and `jj new --after`. It will make it much easier to have a correct implementation of `jj rebase -r --after`, even when rebasing onto a descendant. - The de-duplication is no longer O(n^2). I tried to keep the common case fast. ## Alternatives - We could make `jj rebase` and `jj new` use a separate function with the algorithm shown here, without changing DescendantRebaser. I believe that the new algorithm makes DescendatRebaser easier to understand, though, and it feels more elegant to reduce code duplication. - The de-duplication optimization here is independent of other changes, and could be used on its own.
As suggested by @yuja in jj-vcs#2646 (comment)
As suggested by @yuja in jj-vcs#2646 (comment)
PR Notes
This could be reviewed now or together with the other refactors that would happen in subsequent commits (making
new_parents
a public function, etc). If you prefer the latter, let me know. You can also look at https://github.com/ilyagr/jj/tree/refactor, but it's stillunpolished.
I'm posting this mainly to illustrate my plans, and so that you can let me know if there is some fatal problem with them.
Commit description
Previously, the function relied on both the
self.parent_mapping
andself.rebased
. If(A,B)
was inparent_mapping
and(B,C)
was inrebased
,new_parents
would mapA
toC
.Now,
self.rebased
is ignored bynew_parents
. In the same situation, DescendantRebaser is changed so that both(A,B)
and(B,C)
are inparent_mapping
before.new_parents
now appliesparent_mapping
repeatedly, and will mapA
toC
in this situation.Cons
new_parents
now panics ifself.parent_mapping
contain cycles. AFAICT, such cycles never happen injj
anyway, except for one test that I had to fix. I think it's a sensible restriction to live with; if you do want to swap children of two commits, you can callrebase_descendants
twice.Pros
I find the new logic much easier to reason about. I plan to extract it into a function, to be used in refactors for
jj rebase -r
andjj new --after
. It will make it much easier to have a correct implementation ofjj rebase -r --after
, even when rebasing onto a descendant.The de-duplication is no longer O(n^2). I tried to keep the common case fast.
Alternatives
We could make
jj rebase
andjj new
use a separate function with the algorithm shown here, without changing DescendantRebaser. I believe that the new algorithm makes DescendatRebaser easier to understand, though, and it feels more elegant to reduce code duplication.The de-duplication optimization here is independent of other changes, and could be used on its own.
Checklist
If applicable:
CHANGELOG.md